#include "CStateGraveyard.h"

#include "CNetworkManager.h"
#include "CNetworkIO.h"
#include "COverlord.h"
#include "CMinion.h"
#include "CMinionInfoPanel.h"

CStateGraveyard::CStateGraveyard(CGameManager * mgr) : CState(mgr)
{
  chosen = 0;
  infoPanel = 0;
  minion_base = CMinion::minion_base;
}

CStateGraveyard::~CStateGraveyard()
{
  parent->remove();
}


void CStateGraveyard::init()
{
  parent = env->addTab (rect<s32>(0, 0, 800, 600));

  //env->addImage(driver->getTexture("Dracula.jpg"), position2d<s32> (0,0), true, parent, -1, L"Noob");
  IGUIImage* background = env->addImage( rect<s32>(0,0,SCREEN_W, SCREEN_H), parent, -1, L"L.O.N.");
  background->setImage(driver->getTexture("front2.png"));
  background->setScaleImage(true);


  IGUIImage* background2 = env->addImage( rect<s32>(0,0,800,40), parent, -1, L"L.O.N.");
  background2->setImage(driver->getTexture("baseline.jpg"));
  background2->setScaleImage(true);

  IGUIImage* background3 = env->addImage( rect<s32>(0,560,800,600), parent, -1, L"L.O.N.");
  background3->setImage(driver->getTexture("lowbaseline.jpg"));
  background3->setScaleImage(true);

  IGUIImage * bg= env->addImage( rect<s32>(600, 0, 800, 600), parent);
  bg->setImage(driver->getTexture("sidebar.png"));
  bg->setScaleImage(true);
  bg->setUseAlphaChannel(true);

  // create a button
  env->addButton(rect<s32>(620, 475, 780, 500), parent, BTN_BUY_MINION, L"Buy Minion");
  env->addButton(rect<s32>(620, 515, 780, 540), parent, BTN_SELL_MINION, L"Disown Minion");
  env->addButton(rect<s32>(620, 555, 780, 580), parent, BTN_POPSTATE, L"Back");

/*
  IGUIImage* minionlistborder = env->addImage( rect<s32>(600,70,790, 300), parent);
  minionlistborder->setImage(driver->getTexture("backM2.png"));
  minionlistborder->setScaleImage(true);
  minionlistborder->setUseAlphaChannel(true);
*/

  lstMinion = env->addListBox(rect<s32>(620, 100, 780, 300), parent, LST_MINION);

  //! Minions Details
  //! OVERLORD DETAILS
  COverlord *player = mgr->getPlayer();

  //! Minions Details
  for (u8 i=0; i<player->getMinionCount(); i++)
  {
    CMinion *pMinion = player->getMinion(i);
    //addMinionPanel(pMinion, i);
    lstMinion->addItem(pMinion->getStats().name.c_str());
    lstMinion->setItemOverrideColor(i, EGUI_LBC_TEXT, SColor(255, 255, 255, 255));
  }
}

void CStateGraveyard::close()
{
  parent->remove();
}

void CStateGraveyard::run()
{
  driver->beginScene(true, true, SColor(255,0,0,0));
  smgr->drawAll();

  env->drawAll();

}


void CStateGraveyard::enable()
{
  parent->setVisible(true);
}

void CStateGraveyard::disable()
{
  parent->setVisible(false);
}

//! Event Receiving Methods
void CStateGraveyard::OnServerPacketReceived(Packet *packet)
{
  switch (packet->data[0])
  {

    case ID_LON_GY_ADD_MINION:
      addMinion(new BitStream(packet->data, packet->length, false));
      break;

    case ID_LON_GY_REMOVE_MINION:
      removeMinion(new BitStream(packet->data, packet->length, false));
      break;

/*
    /// Default RakNet Messages
    case ID_DISCONNECTION_NOTIFICATION:
      env->addMessageBox(L"Error",L"You have been disconnected.")->setID(MSG_DISCONNECT);
      break;

    case ID_CONNECTION_LOST:
      env->addMessageBox(L"Error",L"Connection Lost.")->setID(MSG_DISCONNECT);
      break;
*/
    default:
      std::cout << "Message with identifier " << int (packet->data[0]) << " has arrived.\n" << std::endl;
      break;
  }
}

void CStateGraveyard::OnClientPacketReceived(Packet *packet)
{
  //! TODO: Future feature implementation
}
//! Called when mouse is clicked
bool CStateGraveyard::OnMouseClick()
{

  position2d<s32> cursor = device->getCursorControl()->getPosition();

  IGUIElement* element = env->getRootGUIElement ()->getElementFromPoint(cursor);
  if ( element->getID() >= PANEL_MINION )
  {
    if ( chosen != 0 && chosen == element )
    {
      chosen = 0;
      static_cast<IGUIStaticText*>(element)->setBackgroundColor(SColor(64, 0, 0, 255 ));
    }
    else
    {
      if ( chosen != 0 )
      {
        chosen->setBackgroundColor(SColor(0, 255, 255, 255 ));
      }

      chosen = static_cast<IGUIStaticText*>(element);

      static_cast<IGUIStaticText*>(element)->setBackgroundColor(SColor(64, 255, 0, 0));
    }
  }
  return false;
}

//! Called when a GUI button
bool CStateGraveyard::OnButtonClick(s32 id)
{
  switch (id)
  {
    case BTN_POPSTATE:
      mgr->popState();
      return true;
      break;

    case BTN_BUY_MINION:
      // Show add minion window
      showMinionWindow();
      return true;
      break;

    case BTN_BUY_OK:
      requestAddMinion();
      return true;
      break;

    case BTN_BUY_CANCEL:
      minionWindow->remove();
      return true;
      break;

    case BTN_SELL_MINION:
      requestRemoveMinion();
      return true;
      break;
  }

  return false;
}

bool CStateGraveyard::OnGUIEvent(const SEvent& event)
{
  s32 id = event.GUIEvent.Caller->getID();

  switch(event.GUIEvent.EventType)
  {

    case EGET_ELEMENT_LEFT:
      if ( id >= PANEL_MINION )
        if ( chosen == event.GUIEvent.Caller )
          static_cast<IGUIStaticText*>(event.GUIEvent.Caller)->setBackgroundColor(SColor(64, 255, 0, 0 ));
        else
          static_cast<IGUIStaticText*>(event.GUIEvent.Caller)->setBackgroundColor(SColor(0, 255, 255, 255 ));
      break;

    case EGET_ELEMENT_HOVERED:
      if ( id >= PANEL_MINION )
        static_cast<IGUIStaticText*>(event.GUIEvent.Caller)->setBackgroundColor(SColor(64, 0, 0, 255 ));
      break;

    case EGET_LISTBOX_CHANGED:
    case EGET_LISTBOX_SELECTED_AGAIN:
      if ( id == LST_MINION )
      {
        if (lstMinion->getSelected() != -1)
        {
          CMinion *pMinion = mgr->getPlayer()->getMinion(lstMinion->getSelected());
          if ( infoPanel != 0 )
            delete infoPanel;

          s32 x = 20; s32 y = 20;
          infoPanel = new CMinionInfoPanel(device, static_cast<IGUIElement*>(parent), pMinion, x, y);
        }
        return true;
      }
      break;

    default:
      break;
  }

  return false;
}

void CStateGraveyard::showMinionWindow()
{
  minionWindow = env->addWindow(rect <s32> (100, 100 ,350 ,280), true, L"Buy New Minion", parent);

  env->addStaticText(L"Name of the new Minion: ", rect<s32>(25, 25, 225, 50), false, false, minionWindow);
  txtMinionName = env->addEditBox(L"", rect<s32>(25, 60, 225, 85), true, minionWindow);

  comMinionType = env->addComboBox(rect<s32>(25, 95, 225, 120), minionWindow);

  std::map<int,minionStats>::iterator it;
  for ( it=minion_base.begin() ; it != minion_base.end(); ++it )
  {
    int minion_type_id = (*it).first;
    minionStats& stat = (*it).second;
    comMinionType->addItem(stat.typeName.c_str(), minion_type_id);
  }

  env->addButton(rect<s32>(25, 130, 105, 155), minionWindow, BTN_BUY_OK, L"Buy");
  env->addButton(rect<s32>(115, 130, 195, 155), minionWindow, BTN_BUY_CANCEL, L"Cancel");
}

void CStateGraveyard::requestAddMinion()
{
  int index = comMinionType->getSelected();

  if ( index == -1 )
    return;

  u8 type = comMinionType->getItemData(index); // Minion type;
  BitStream bs;
  bs.Write(u8(ID_LON_GY_ADD_MINION));
  bs.Write( type ); // Write the type id of the minion to be added
  CNetworkIO::writeWcs(bs, txtMinionName->getText());

  mgr->getNetworkManager()->sendPacket(&bs);
}

void CStateGraveyard::requestRemoveMinion()
{
  u8 idx = lstMinion->getSelected();

  if ( lstMinion->getSelected() == -1 )
    return;

  CMinion *minion = mgr->getPlayer()->getMinion(idx);

  BitStream bs;
  bs.Write(u8(ID_LON_GY_REMOVE_MINION));
  bs.Write(minion->minion_id()); // Write the id of the removing minion

  mgr->getNetworkManager()->sendPacket(&bs);
}

void CStateGraveyard::addMinion(BitStream *bs)
{
  u8 msgId;
  u8 idx;
  u32 minion_id;
  minionStats stats;

  // Read packet
  bs->Read(msgId);
  bs->Read(minion_id);
  stats.netRead(*bs);

  CMinion *pMinion = new CMinion(stats);
  pMinion->set_minion_id(minion_id);
  mgr->getPlayer()->addMinion(pMinion);

  // Add a freakin panel
  idx = lstMinion->addItem(pMinion->getStats().name.c_str());
  lstMinion->setItemOverrideColor(idx, EGUI_LBC_TEXT, SColor(255, 255, 255, 255));

  delete bs;
}

void CStateGraveyard::removeMinion(BitStream *bs)
{
  u8 msgId;
  u32 minion_id;
  bs->Read(msgId);
  bs->Read(minion_id);

  u32 index = mgr->getPlayer()->getMinionIndex(minion_id);

  lstMinion->removeItem(index);
  lstMinion->setSelected(index);
  mgr->getPlayer()->removeMinion(index);

  delete bs;
}

